package is.ru.tgra;
import java.util.ArrayList;
import java.util.Random;
import java.util.Vector;

import com.badlogic.gdx.graphics.GL11;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;


public class First3D_Core implements ApplicationListener {
	Camera cam;
	Sphere sphere;
	Sphere test;
	ParticleEffect particleEffect;
	ParticleEffect testParticle;
	Planet planets[];
	
	boolean animate;
	
	Skybox skybox;
	
	int numOfPlanets;
	
	Light light;
	
	float a = 25f;
	float b = 15f;
	float c = 10f;
	float time;
	
	Random n = new Random();
	Random m = new Random();
	Random p = new Random();
	
	
	Quad background;
	
	float rotationAngle = 0.0f;
	float deltaTime = 0.0f;
	
	float orbitTime = 0.0f;
	
	@Override
	public void create() {

		animate = false;
		Gdx.gl11.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

		// Set up the projection matrix.
		Gdx.gl11.glMatrixMode(GL11.GL_PROJECTION);
		Gdx.gl11.glLoadIdentity();
		Gdx.glu.gluPerspective(Gdx.gl11, 90, 1.628498728f, 0.02f, 100.0f);

		Gdx.gl11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
		cam = new Camera(new Point3D(1.0f, 1.0f, 50.0f), new Point3D(1.0f, 2.5f, 0.0f), new Vector3D(0.0f, 1.0f, 0.0f));
		
		light = new Light(new Point3D(1.0f, 2.5f, 4.0f), new Point3D(0.0f, 2.5f, 0.0f), new Vector3D(0.0f, 1.0f, 0.0f));
		test = new Sphere(50,20);
		
		planets = SolarSystem.createPlanets();
		skybox = new Skybox();
		
		
		sphere = new Sphere(50, 24);
		this.particleEffect = new ParticleEffect();
		this.testParticle = new ParticleEffect("northern.jpg");
		this.background = new Quad("assets/textures/space.png");
	}

	@Override
	public void dispose() {	}

	@Override
	public void pause() { }

	
	private void update() {
		float deltaTime = Gdx.graphics.getDeltaTime();
		
		this.deltaTime = deltaTime;
		this.orbitTime = orbitTime + deltaTime;
		rotationAngle += 10.0f * deltaTime;
		
		if(Gdx.input.isKeyPressed(Input.Keys.C) && animate == true)
		{
			animate = false;
		}
		else if (Gdx.input.isKeyPressed(Input.Keys.C) && animate == false)
		{
			animate = true;
		}
		
		
		if(!animate)
		{
			Controls.animate(cam, deltaTime);			
		}
		else
		{
			Controls.keyboard(cam, deltaTime);
		}
		
		
		
		this.particleEffect.update(deltaTime);
		
		
		for(int i = 0; i < numOfPlanets; i++)
		{
			planets[i].slide(0.0f, 0.0f, planets[i].getRadius() * deltaTime/3);
			planets[i].yaw(-90.0f * deltaTime+planets[i].getOrbitSpeed());
			
		}
		
	}

	
	private void display()
	{
		

		Gdx.gl11.glClear(GL11.GL_COLOR_BUFFER_BIT|GL11.GL_DEPTH_BUFFER_BIT);
		
		Gdx.gl11.glDisable(GL11.GL_LIGHTING);
		Gdx.gl11.glDisable(GL11.GL_DEPTH_TEST);
		Gdx.gl11.glMatrixMode(GL11.GL_PROJECTION);
		Gdx.gl11.glPushMatrix();
		Gdx.gl11.glLoadIdentity();
		Gdx.gl11.glOrthof(0, 1, 0, 1, 0, 1);
		
		
		Gdx.gl11.glMatrixMode(GL11.GL_MODELVIEW);
		Gdx.gl11.glPushMatrix();
		Gdx.gl11.glLoadIdentity();
		
		
		Gdx.gl11.glDepthMask(false);
		
		//this.background.draw();
		
		Gdx.gl11.glDepthMask(true);
		
		// pop model view matrix
		Gdx.gl11.glPopMatrix();
		
		Gdx.gl11.glMatrixMode(GL11.GL_PROJECTION);
		
		// pop the projection matrix.
		Gdx.gl11.glPopMatrix();
		
		Gdx.gl11.glMatrixMode(GL11.GL_MODELVIEW);
		
		
		// Set the ModelView matrix with respect to the camera.
		cam.setModelViewMatrix();
		
		
		Gdx.gl11.glEnable(GL11.GL_LIGHTING);
		Gdx.gl11.glEnable(GL11.GL_LIGHT0);
		Gdx.gl11.glEnable(GL11.GL_LIGHT1);
		Gdx.gl11.glEnable(GL11.GL_DEPTH_TEST);
		
		
		Gdx.gl11.glPushMatrix();
		Gdx.gl11.glTranslatef(0f, 0.5f, 0f);
		
		this.particleEffect.display();

		Gdx.gl11.glPopMatrix();
		
		
		Gdx.gl11.glMaterialf(GL11.GL_FRONT, GL11.GL_SHININESS, 100.0f);

		float[] lightDiffuse = {0.8f, 0.8f, 0.7f, 1.0f};
		float[] lightAmbient = {1.0f, 1.0f, 1.0f, 1.0f};
		Gdx.gl11.glLightfv(GL11.GL_LIGHT0, GL11.GL_DIFFUSE, lightDiffuse, 0);
		Gdx.gl11.glLightfv(GL11.GL_LIGHT0, GL11.GL_AMBIENT, lightAmbient, 0);

		float[] lightPosition = {1.0f, 1.0f, 1.0f, 1.0f};
		Gdx.gl11.glLightfv(GL11.GL_LIGHT0, GL11.GL_POSITION, lightPosition, 0);

		float[] lightDiffuse1 = {0.8f, 0.8f, 0.7f, 1.0f};
		Gdx.gl11.glLightfv(GL11.GL_LIGHT1, GL11.GL_DIFFUSE, lightDiffuse1, 0);

		float[] lightPosition1 = {0.0f, 5.0f, 10.0f, 1.0f};
		Gdx.gl11.glLightfv(GL11.GL_LIGHT1, GL11.GL_POSITION, lightPosition1, 0);


		float[] materialDiffuse = {10.0f, 10.0f, 10.0f, 10.0f};
		Gdx.gl11.glMaterialfv(GL11.GL_FRONT, GL11.GL_DIFFUSE, materialDiffuse, 0);
		
		float[] specLight0 = {0.5f, 0.5f, 0.5f, 1.0f};
		Gdx.gl11.glLightfv(GL11.GL_LIGHT0, GL11.GL_SPECULAR, specLight0, 0);
		Gdx.gl11.glMaterialfv(GL11.GL_FRONT, GL11.GL_SHININESS, materialDiffuse, 0); 




		for(int i = 0; i < SolarSystem.numOfPlanets ; i++)
		{
			drawPlanet(planets[i]);
		}
		
		Gdx.gl11.glPushMatrix();
		Gdx.gl11.glTranslatef(cam.eye.x, cam.eye.y, cam.eye.z);
		Gdx.gl11.glScalef(150f,150f,150f);
		skybox.Render();
		Gdx.gl11.glPopMatrix();
		
		
	
	}
	
	
	
	
	
	private void drawPlanet(Planet planet)
	{	
		
		
		float s = planet.getSize();
		
		float x = SolarSystem.findX(planet.getRadius(), orbitTime, planet.getOrbitSpeed());
		float z = SolarSystem.findZ(planet.getRadius(), orbitTime, planet.getOrbitSpeed());
		

		
		Gdx.gl11.glPushMatrix();
		if (planet.pos.z == 1.6f) //the moon
		{
			Gdx.gl11.glTranslatef(x, planet.pos.y, z+0.6f);
		}
		else
		{
			Gdx.gl11.glTranslatef(x, planet.pos.y, z);
		}
		
		Gdx.gl11.glScalef(s,s,s);

		Gdx.gl11.glRotatef(rotationAngle, 0.0f, 1.0f, 0.0f);
		planet.draw();
		Gdx.gl11.glPopMatrix();
	}
	

	@Override
	public void render()
	{
		update();
		display();
	}

	@Override
	public void resize(int arg0, int arg1) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void resume() {
		// TODO Auto-generated method stub
		
	}
	
	public void MoveParticles()
	{
		this.a -= deltaTime*2;
		this.b -= deltaTime*2;
		this.c -= deltaTime*c;
	}


	public void updateNumbers()
	{
		time += deltaTime;
		if(time > 10)
		{
			a = n.nextFloat() * 40;
			b = m.nextFloat() * 45;
			c = p.nextFloat() * 32;
			time = 0f;
		}
	}
	
	public void CreateParticles()
	{
		
		Gdx.gl11.glEnable(GL11.GL_LIGHTING);
		Gdx.gl11.glEnable(GL11.GL_LIGHT0);
		Gdx.gl11.glEnable(GL11.GL_LIGHT1);
		Gdx.gl11.glEnable(GL11.GL_DEPTH_TEST);
		
		
		Gdx.gl11.glPushMatrix();
		Gdx.gl11.glTranslatef(a,b,c);
		
		this.testParticle.display();
		
		Gdx.gl11.glPopMatrix();
	}

}
